//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Core.h".
//-------------------------------------------------------------------

#ifndef _UXS_BASE_FILE_H
#define _UXS_BASE_FILE_H

#pragma once

#include "../Types/CReferenced.h"
#include "../Types/TSimplePtr.h"

namespace UX_STL
{
namespace File
{
	using namespace UXTypes;

	
	struct EFile
	{
		enum type
		{
			UNKNOWN	= 0,
			HDD,
			MEMORY,
			RESOURCE,	// platform depended file type
			SUB_FILE,
			CRYPTED,

			_ARCHIVE	= 0x1000,
			ZIP,
			LZMA,
		};

		inline bool IsArchive (type t)
		{
			return t > _ARCHIVE;
		}
	};


	//
	// Base File interface
	//

	class BaseFile : protected CReferenced
	{
	// interface
	public:
		virtual ~BaseFile () {}

		virtual void Close () = 0;

		virtual bool IsOpened () = 0;

		virtual bool SeekSet (usize offset) = 0;
		virtual bool SeekCur (isize offset) = 0;
		virtual bool SeekEnd (usize offset) = 0;

		virtual usize RemainingSize () const = 0;
		virtual usize Size () const = 0;
		virtual usize Pos () const = 0;
		virtual usize IsEOF () const = 0;

		virtual EFile::type		GetType () const = 0;
		virtual uni_c_string	Name () const = 0;
	};



	//
	// Read only File interface
	//

	class RFile : public BaseFile
	{
	// types
	public:
		SHARED_POINTER( RFile );


	// methods
	public:
		virtual isize ReadBuf (void * buf, usize size) = 0;

		bool Read (void * buf, usize size)
		{
			return ReadBuf( buf, size ) == (isize) size;
		}

		template <typename T>
		bool Read (T & value)
		{
			return ReadBuf( &value, sizeof(value) ) == sizeof(value);
		}

		template <typename T>
		T ReadValue ()
		{
			T value;
			Read( value );
			return value;
		}
	};



	//
	// Write only File interface
	//

	class WFile : public BaseFile
	{
	// types
	public:
		SHARED_POINTER( WFile );


	// methods
	public:
		virtual isize WriteBuf (const void * buf, usize size) = 0;

		virtual void Flush () = 0;

		bool Write (const void * buf, usize size)
		{
			return WriteBuf( buf, size ) == (isize) size;
		}

		template <typename T>
		bool Write (const T & value)
		{
			return WriteBuf( &value, sizeof(value) ) == sizeof(value);
		}
	};


}	// File


namespace UXTypes
{
	typedef SHARED_POINTER_TYPE( File::RFile )	RFilePtr;
	typedef SHARED_POINTER_TYPE( File::WFile )	WFilePtr;

}	// UXTypes
}	// UX_STL

#endif	// _UXS_BASE_FILE_H